package usercenter

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ UserRewardStatModel = (*customUserRewardStatModel)(nil)

type (
	// UserRewardStatModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserRewardStatModel.
	UserRewardStatModel interface {
		userRewardStatModel
		InsertTrans(ctx context.Context, tx sqlx.Session, data *UserRewardStat) (sql.Result, error)
		Incr(ctx context.Context, tx sqlx.Session, uid int64, cnt int64) error
		Decr(ctx context.Context, tx sqlx.Session, uid int64, cnt int64) error
	}

	customUserRewardStatModel struct {
		*defaultUserRewardStatModel
	}
)

// NewUserRewardStatModel returns a model for the database table.
func NewUserRewardStatModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserRewardStatModel {
	return &customUserRewardStatModel{
		defaultUserRewardStatModel: newUserRewardStatModel(conn, c, opts...),
	}
}

func (m *customUserRewardStatModel) InsertTrans(ctx context.Context, tx sqlx.Session, data *UserRewardStat) (sql.Result, error) {
	mumbaiUserRewardStatUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserRewardStatUidPrefix, data.Uid)
	ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?)", m.table, userRewardStatRowsExpectAutoSet)
		return tx.ExecCtx(ctx, query, data.Uid, data.NotReceived, data.Total)
	}, mumbaiUserRewardStatUidKey)
	return ret, err
}

func (m *customUserRewardStatModel) Incr(ctx context.Context, tx sqlx.Session, uid int64, cnt int64) error {
	mumbaiUsercenterUserRewardStatUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserRewardStatUidPrefix, uid)
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set total=total+?, not_received=not_received+? where uid = ?", m.table)
		return tx.ExecCtx(ctx, query, cnt, cnt, uid)
	}, mumbaiUsercenterUserRewardStatUidKey)
	return err
}

func (m *customUserRewardStatModel) Decr(ctx context.Context, tx sqlx.Session, uid int64, cnt int64) error {
	mumbaiUsercenterUserRewardStatUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserRewardStatUidPrefix, uid)
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set not_received=not_received-? where uid = ?", m.table)
		return tx.ExecCtx(ctx, query, cnt, uid)
	}, mumbaiUsercenterUserRewardStatUidKey)
	return err
}
